# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
from dezero import Variable
import dezero.functions as F
import dezero.layers as L
"""
创建非线性数据集
根据输入x 预测输出y 图像为sin
实现线性回归
"""
#创建数据
np.random.seed(0)
x = np.random.rand(100,1)
y = np.random.rand(100,1) + np.sin(2 * np.pi * x)

l1 = L.Linear(10) #第一层输出10个变量
l2 = L.Linear(1) #自动会判断前一层的输入个数

# #创建初始权重和偏差
# I,H,O = 1,10,1 #I输入层维度，H隐藏层维度，O输出层维度
# W1,b1 = Variable(0.01 * np.random.randn(I,H)),Variable(np.zeros(H))
# W2,b2 = Variable(0.01 * np.random.randn(H,O)),Variable(np.zeros(O))
#
#神经网络的推理
def predict(x):
    #y = F.linear(x,w,b)
    y = l1(x)
    y = F.sigmoid(y)
    y = l2(y)
    return y

#超参调整
lr = 0.2
epoch = 10000

#神经网络的训练
for i in range(epoch):
    y_pred = predict(x)
    loss = F.mean_squared_error(y, y_pred)
    # W1.cleargrad()
    # b1.cleargrad()
    # W2.cleargrad()
    # b2.cleargrad()
    l1.cleargrads()
    l2.cleargrads()
    loss.backward()

    #更新参数
    # W1.data -= lr * W1.grad.data
    # b1.data -= lr * b1.grad.data
    # W2.data -= lr * W2.grad.data
    # b2.data -= lr * b2.grad.data
    for l in [l1,l2]:
        for p in l.params():
            p.data -= lr * p.grad.data

    # if i % 1000 == 0:
    #     print(loss)

#plot
plt.scatter(x,y)
plt.xlabel('x')
plt.ylabel('y')

# t = np.arange(0, 1, 0.01)[:, np.newaxis]
t = np.arange(0, 1, 0.01)
tt = np.expand_dims(t,1)
y_pred = predict(tt)
plt.plot(t,y_pred.data,color='black')

plt.show()